// Protocol3 协议测试工具
// 提供协议验证、性能测试、协议绑定测试和批量测试功能

import type {
  MerchantChannelConfig3,
  QRCodeConfig,
  ProtocolBinding,
  ValidationResult,
  TestResult
} from '../types/protocol3-types'
import {
  validateFieldValue,
  mergeValidationResults,
  formatTimestamp,
  ProtocolBindingStatus
} from '../types/protocol3-types'
import { protocol3Manager } from './protocol3-manager'
import { protocol3Resolver } from './protocol3-resolver'

// 测试配置接口
export interface TestConfig {
  validateStructure: boolean
  validateFields: boolean
  testResolution: boolean
  testBindings: boolean
  testPerformance: boolean
  iterations: number
}

// 性能测试结果
export interface PerformanceTestResult {
  totalTime: number
  averageTime: number
  minTime: number
  maxTime: number
  iterations: number
  throughput: number
}

// 协议绑定测试结果
export interface BindingTestResult {
  success: boolean
  errors: string[]
  warnings: string[]
  bindingCount: number
  activeBindings: number
  inactiveBindings: number
  resolutionTests: Array<{
    channelCode: string
    configType: string
    success: boolean
    protocolId?: string
    isDefault: boolean
  }>
}

// 批量测试结果
export interface BatchTestResult {
  totalTests: number
  passedTests: number
  failedTests: number
  results: TestResult[]
  summary: {
    structureErrors: number
    fieldErrors: number
    resolutionErrors: number
    bindingErrors: number
    performanceIssues: number
  }
}

// Protocol3 测试器
export class Protocol3Tester {
  private static instance: Protocol3Tester
  
  private constructor() {
    // 私有构造函数，确保单例
  }
  
  public static getInstance(): Protocol3Tester {
    if (!Protocol3Tester.instance) {
      Protocol3Tester.instance = new Protocol3Tester()
    }
    return Protocol3Tester.instance
  }
  
  /**
   * 测试单个协议
   */
  public testProtocol(protocolId: string, config: Partial<TestConfig> = {}): TestResult {
    const startTime = Date.now()
    const testConfig: TestConfig = {
      validateStructure: true,
      validateFields: true,
      testResolution: true,
      testBindings: true,
      testPerformance: false,
      iterations: 100,
      ...config
    }
    
    const errors: string[] = []
    const warnings: string[] = []
    const details: any = {}
    
    try {
      // 获取协议配置
      const protocol = protocol3Manager.getProtocol(protocolId)
      if (!protocol) {
        errors.push(`协议 ${protocolId} 不存在`)
        return this.createTestResult(false, errors, warnings, Date.now() - startTime, details)
      }
      
      // 1. 结构验证
      if (testConfig.validateStructure) {
        const structureResult = this.validateProtocolStructure(protocol)
        if (!structureResult.valid) {
          errors.push(...structureResult.errors)
        }
        details.structureValidation = structureResult
      }
      
      // 2. 字段验证
      if (testConfig.validateFields) {
        const fieldsResult = this.validateProtocolFields(protocol)
        if (!fieldsResult.valid) {
          warnings.push(...fieldsResult.errors)
        }
        details.fieldsValidation = fieldsResult
      }
      
      // 3. 协议绑定测试
      if (testConfig.testBindings) {
        const bindingResult = this.testProtocolBindings(protocol)
        if (!bindingResult.success) {
          warnings.push(...bindingResult.errors)
        }
        details.bindingTest = bindingResult
      }
      
      // 4. 性能测试
      if (testConfig.testPerformance) {
        const performanceResult = this.testProtocolPerformance(protocol, testConfig.iterations)
        if (performanceResult.averageTime > 100) { // 超过100ms认为性能问题
          warnings.push(`协议解析平均耗时 ${performanceResult.averageTime.toFixed(2)}ms，可能存在性能问题`)
        }
        details.performanceTest = performanceResult
      }
      
      const duration = Date.now() - startTime
      const success = errors.length === 0
      
      return this.createTestResult(success, errors, warnings, duration, details)
      
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : String(error)
      errors.push(`测试过程中发生异常: ${errorMessage}`)
      return this.createTestResult(false, errors, warnings, Date.now() - startTime, details)
    }
  }
  
  /**
   * 批量测试所有协议
   */
  public testAllProtocols(config: Partial<TestConfig> = {}): BatchTestResult {
    const protocols = protocol3Manager.getAllProtocols()
    const results: TestResult[] = []
    
    let passedTests = 0
    let failedTests = 0
    const summary = {
      structureErrors: 0,
      fieldErrors: 0,
      resolutionErrors: 0,
      bindingErrors: 0,
      performanceIssues: 0
    }
    
    for (const protocol of protocols) {
      const result = this.testProtocol(protocol.protocolId, config)
      results.push(result)
      
      if (result.success) {
        passedTests++
      } else {
        failedTests++
      }
      
      // 统计错误类型
      if (result.details?.structureValidation && !result.details.structureValidation.valid) {
        summary.structureErrors++
      }
      if (result.details?.fieldsValidation && !result.details.fieldsValidation.valid) {
        summary.fieldErrors++
      }
      if (result.details?.bindingTest && !result.details.bindingTest.success) {
        summary.bindingErrors++
      }
      if (result.details?.performanceTest && result.details.performanceTest.averageTime > 100) {
        summary.performanceIssues++
      }
    }
    
    return {
      totalTests: protocols.length,
      passedTests,
      failedTests,
      results,
      summary
    }
  }
  
  /**
   * 测试协议解析性能
   */
  public testProtocolPerformance(protocol: MerchantChannelConfig3 | QRCodeConfig, iterations: number = 1000): PerformanceTestResult {
    const times: number[] = []
    const configType = protocol.protocolType === 'QR_CODE_CONFIG' ? 'QR_CODE_CONFIG' : 'MERCHANT_CONFIG'
    
    for (let i = 0; i < iterations; i++) {
      const startTime = performance.now()
      protocol3Resolver.resolveProtocol('TEST_CHANNEL', configType)
      const endTime = performance.now()
      times.push(endTime - startTime)
    }
    
    const totalTime = times.reduce((sum, time) => sum + time, 0)
    const averageTime = totalTime / iterations
    const minTime = Math.min(...times)
    const maxTime = Math.max(...times)
    const throughput = 1000 / averageTime // 每秒处理数
    
    return {
      totalTime,
      averageTime,
      minTime,
      maxTime,
      iterations,
      throughput
    }
  }
  
  /**
   * 测试协议绑定系统
   */
  public testProtocolBindings(protocol: MerchantChannelConfig3 | QRCodeConfig): BindingTestResult {
    const errors: string[] = []
    const warnings: string[] = []
    const resolutionTests: Array<{
      channelCode: string
      configType: string
      success: boolean
      protocolId?: string
      isDefault: boolean
    }> = []
    
    try {
      // 获取协议的所有绑定
      const bindings = protocol3Manager.getProtocolBindings(protocol.protocolId)
      
      let activeBindings = 0
      let inactiveBindings = 0
      
      for (const binding of bindings) {
        if (binding.status === ProtocolBindingStatus.ACTIVE) {
          activeBindings++
          
          // 测试绑定解析
          try {
            const resolveResult = protocol3Resolver.resolveProtocol(binding.channelCode, binding.configType)
            resolutionTests.push({
              channelCode: binding.channelCode,
              configType: binding.configType,
              success: resolveResult.protocol.protocolId === protocol.protocolId,
              protocolId: resolveResult.protocol.protocolId,
              isDefault: resolveResult.isDefault
            })
          } catch (error) {
            resolutionTests.push({
              channelCode: binding.channelCode,
              configType: binding.configType,
              success: false,
              isDefault: false
            })
            errors.push(`绑定解析失败: ${binding.channelCode}:${binding.configType}`)
          }
        } else {
          inactiveBindings++
        }
      }
      
      // 检查绑定状态
      if (bindings.length === 0) {
        warnings.push('协议未创建任何绑定')
      }
      
      if (activeBindings === 0 && bindings.length > 0) {
        warnings.push('协议有绑定但无激活状态的绑定')
      }
      
      return {
        success: errors.length === 0,
        errors,
        warnings,
        bindingCount: bindings.length,
        activeBindings,
        inactiveBindings,
        resolutionTests
      }
      
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : String(error)
      errors.push(`绑定测试异常: ${errorMessage}`)
      
      return {
        success: false,
        errors,
        warnings,
        bindingCount: 0,
        activeBindings: 0,
        inactiveBindings: 0,
        resolutionTests
      }
    }
  }
  
  /**
   * 测试协议绑定系统整体功能
   */
  public testBindingSystem(): {
    success: boolean
    errors: string[]
    warnings: string[]
    statistics: any
  } {
    const errors: string[] = []
    const warnings: string[] = []
    
    try {
      // 获取绑定统计信息
      const statistics = protocol3Resolver.getBindingStatistics()
      
      // 检查绑定系统状态
      if (statistics.totalBindings === 0) {
        warnings.push('系统中没有协议绑定')
      }
      
      if (statistics.activeBindings === 0) {
        warnings.push('系统中没有激活的协议绑定')
      }
      
      if (statistics.activeBindings / statistics.totalBindings < 0.5) {
        warnings.push('激活的协议绑定比例过低')
      }
      
      // 测试支持的渠道和配置类型
      const supportedChannels = protocol3Resolver.getSupportedChannels()
      const channelConfigTypes = protocol3Manager.getChannelConfigTypes()
      
      if (supportedChannels.length === 0) {
        errors.push('系统没有支持的渠道')
      }
      
      if (channelConfigTypes.length === 0) {
        errors.push('系统没有配置的渠道配置类型')
      }
      
      return {
        success: errors.length === 0,
        errors,
        warnings,
        statistics: {
          ...statistics,
          supportedChannels,
          channelConfigTypes: channelConfigTypes.length
        }
      }
      
    } catch (error) {
      const errorMessage = error instanceof Error ? error.message : String(error)
      errors.push(`绑定系统测试异常: ${errorMessage}`)
      
      return {
        success: false,
        errors,
        warnings,
        statistics: {}
      }
    }
  }
  
  /**
   * 生成测试报告
   */
  public generateTestReport(results: BatchTestResult): string {
    const report = []
    
    report.push('# Protocol3 测试报告')
    report.push(`生成时间: ${formatTimestamp(Date.now())}`)
    report.push('')
    
    // 总体统计
    report.push('## 总体统计')
    report.push(`- 总测试数: ${results.totalTests}`)
    report.push(`- 通过测试: ${results.passedTests}`)
    report.push(`- 失败测试: ${results.failedTests}`)
    report.push(`- 通过率: ${((results.passedTests / results.totalTests) * 100).toFixed(2)}%`)
    report.push('')
    
    // 错误统计
    report.push('## 错误统计')
    report.push(`- 结构错误: ${results.summary.structureErrors}`)
    report.push(`- 字段错误: ${results.summary.fieldErrors}`)
    report.push(`- 绑定错误: ${results.summary.bindingErrors}`)
    report.push(`- 性能问题: ${results.summary.performanceIssues}`)
    report.push('')
    
    // 绑定系统测试
    const bindingSystemResult = this.testBindingSystem()
    report.push('## 绑定系统测试')
    report.push(`- 状态: ${bindingSystemResult.success ? '✅ 正常' : '❌ 异常'}`)
    report.push(`- 总绑定数: ${bindingSystemResult.statistics.totalBindings || 0}`)
    report.push(`- 激活绑定数: ${bindingSystemResult.statistics.activeBindings || 0}`)
    report.push(`- 支持渠道数: ${bindingSystemResult.statistics.supportedChannels?.length || 0}`)
    
    if (bindingSystemResult.errors.length > 0) {
      report.push('**错误:**')
      bindingSystemResult.errors.forEach(error => report.push(`- ${error}`))
    }
    
    if (bindingSystemResult.warnings.length > 0) {
      report.push('**警告:**')
      bindingSystemResult.warnings.forEach(warning => report.push(`- ${warning}`))
    }
    report.push('')
    
    // 详细结果
    report.push('## 详细结果')
    for (const result of results.results) {
      const status = result.success ? '✅ 通过' : '❌ 失败'
      report.push(`### ${result.protocolId} - ${status}`)
      
      if (result.errors.length > 0) {
        report.push('**错误:**')
        result.errors.forEach(error => report.push(`- ${error}`))
      }
      
      if (result.warnings.length > 0) {
        report.push('**警告:**')
        result.warnings.forEach(warning => report.push(`- ${warning}`))
      }
      
      // 绑定测试结果
      if (result.details?.bindingTest) {
        const bindingTest = result.details.bindingTest
        report.push(`**绑定状态:** ${bindingTest.bindingCount} 个绑定 (${bindingTest.activeBindings} 激活, ${bindingTest.inactiveBindings} 未激活)`)
        
        if (bindingTest.resolutionTests.length > 0) {
          report.push('**解析测试:**')
          bindingTest.resolutionTests.forEach((test: any) => {
            const testStatus = test.success ? '✅' : '❌'
            report.push(`  - ${testStatus} ${test.channelCode}:${test.configType} ${test.isDefault ? '(默认)' : ''}`)
          })
        }
      }
      
      report.push(`**耗时:** ${result.duration}ms`)
      report.push('')
    }
    
    return report.join('\n')
  }
  
  // ==================== 私有方法 ====================
  
  /**
   * 验证协议结构
   */
  private validateProtocolStructure(protocol: MerchantChannelConfig3 | QRCodeConfig): ValidationResult {
    const errors: string[] = []
    
    // 基本字段检查
    if (!protocol.protocolId) {
      errors.push('协议ID不能为空')
    }
    
    if (!protocol.name) {
      errors.push('协议名称不能为空')
    }
    
    if (!protocol.protocolType) {
      errors.push('协议类型不能为空')
    }
    
    if (!protocol.version) {
      errors.push('版本号不能为空')
    }
    
    // 协议类型特定检查
    if (protocol.protocolType === 'QR_CODE_CONFIG') {
      const qrProtocol = protocol as QRCodeConfig
      if (!qrProtocol.codeType) {
        errors.push('二维码类型不能为空')
      }
      if (!['STATIC', 'DYNAMIC'].includes(qrProtocol.codeType)) {
        errors.push('二维码类型必须为STATIC或DYNAMIC')
      }
    }
    
    // 配置段检查
    if (!protocol.configSections || protocol.configSections.length === 0) {
      errors.push('协议必须包含至少一个配置段')
    } else {
      protocol.configSections.forEach((section, index) => {
        if (!section.sectionKey) {
          errors.push(`配置段 ${index + 1} 缺少sectionKey`)
        }
        if (!section.sectionName) {
          errors.push(`配置段 ${index + 1} 缺少sectionName`)
        }
        if (!section.fields || section.fields.length === 0) {
          errors.push(`配置段 ${section.sectionName} 必须包含至少一个字段`)
        }
      })
    }
    
    // UI配置检查
    if (!protocol.uiConfig) {
      errors.push('UI配置不能为空')
    }
    
    // 元数据检查
    if (!protocol.metadata) {
      errors.push('元数据不能为空')
    }
    
    return {
      valid: errors.length === 0,
      errors
    }
  }
  
  /**
   * 验证协议字段
   */
  private validateProtocolFields(protocol: MerchantChannelConfig3 | QRCodeConfig): ValidationResult {
    const results: ValidationResult[] = []
    
    for (const section of protocol.configSections) {
      for (const field of section.fields) {
        // 字段基本信息检查
        if (!field.fieldKey) {
          results.push({ valid: false, errors: [`字段缺少fieldKey`] })
          continue
        }
        
        if (!field.fieldName) {
          results.push({ valid: false, errors: [`字段 ${field.fieldKey} 缺少fieldName`] })
        }
        
        if (!field.fieldType) {
          results.push({ valid: false, errors: [`字段 ${field.fieldKey} 缺少fieldType`] })
        }
        
        // 验证默认值
        if (field.defaultValue !== undefined && field.defaultValue !== null && field.defaultValue !== '') {
          const fieldResult = validateFieldValue(field, field.defaultValue)
          if (!fieldResult.valid) {
            results.push({
              valid: false,
              errors: [`字段 ${field.fieldKey} 默认值验证失败: ${fieldResult.error}`]
            })
          }
        }
      }
    }
    
    return mergeValidationResults(results)
  }
  
  /**
   * 创建测试结果
   */
  private createTestResult(
    success: boolean,
    errors: string[],
    warnings: string[],
    duration: number,
    details?: any,
    protocolId?: string
  ): TestResult {
    return {
      success,
      errors,
      warnings,
      duration,
      details,
      protocolId,
      timestamp: formatTimestamp(Date.now())
    }
  }
}

// 导出单例实例
export const protocol3Tester = Protocol3Tester.getInstance()

// 便捷函数
export function testProtocol3(protocolId: string, config?: Partial<TestConfig>): TestResult {
  return protocol3Tester.testProtocol(protocolId, config)
}

export function testAllProtocol3s(config?: Partial<TestConfig>): BatchTestResult {
  return protocol3Tester.testAllProtocols(config)
}

export function testProtocol3Performance(protocol: MerchantChannelConfig3 | QRCodeConfig, iterations?: number): PerformanceTestResult {
  return protocol3Tester.testProtocolPerformance(protocol, iterations)
}

export function testProtocol3BindingSystem(): any {
  return protocol3Tester.testBindingSystem()
}

export function generateProtocol3TestReport(results: BatchTestResult): string {
  return protocol3Tester.generateTestReport(results)
}

// 默认导出
export default {
  Protocol3Tester,
  protocol3Tester,
  testProtocol3,
  testAllProtocol3s,
  testProtocol3Performance,
  testProtocol3BindingSystem,
  generateProtocol3TestReport
}